﻿using Appliaction.Dto.Inv;
using Domain.Entitys.DB;
using Domain.Entitys.Inv;
using Domain.IRepositorys.Inv;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EFCore.Repositorys.Inv
{
    public class Inv_othoutordRepository : IInv_othoutordRepository
    {
        private readonly MyDbContext myDbContext;

        public Inv_othoutordRepository(MyDbContext myDbContext)
        {
            this.myDbContext = myDbContext;
        }
        /// <summary>
        /// 查看详情信息
        /// </summary>
        /// <param name="Othoutord_code"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<List<Inv_othproddetails>> iInv_othproddetailslSelect(string Othoutord_code)
        {
            var Inv_othwr = await myDbContext.inv_othoutord.Where(e => e.Othoutord_code == Othoutord_code && e.Del_flag == '0').FirstOrDefaultAsync();
            if (Inv_othwr == null)
            {
                throw new Exception("仓库不存在");
            }
            var Othoutord = await myDbContext.inv_othproddetails.Where(e => e.Othoutord_id == Inv_othwr.Othoutord_id).ToListAsync();


            return Othoutord;
        }

        /// <summary>
        /// 分页
        /// </summary>
        /// <param name="searchKeyword"></param>
        /// <param name="othwr_type"></param>
        /// <param name="currentPage"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<othoutordSelectDto> inv_othoutordAsync(string searchKeyword, string othwr_type, int currentPage, int pageSize)
        {
            // 使用 IQueryable 延迟构建查询
            IQueryable<Inv_othoutord> query = myDbContext.inv_othoutord;

            // 条件1: 根据入库类型筛选（如果提供了）
            if (!string.IsNullOrEmpty(othwr_type)) // 假设0表示“全部”或无效值
            {
                query = query.Where(x => x.Othoutord_type == othwr_type);
            }

            // 条件2: 根据关键字搜索（如果提供了）
            if (!string.IsNullOrEmpty(searchKeyword))
            {
                query = query.Where(x => x.Othoutord_code.Contains(searchKeyword));
            }

            // 条件3: 删除标志为未删除（del_flag == '0'）
            query = query.Where(x => x.Del_flag == '0').OrderByDescending(d => d.Create_time);

            var result = query.Skip((currentPage - 1) * pageSize)
                                  .Take(pageSize)
                                  .Select(main => new othoutordSelectDto
                                  {
                                      Othoutord_id = main.Othoutord_id,
                                      Othoutord_type = main.Othoutord_type,
                                      Othoutord_code = main.Othoutord_code,
                                      Warehouse_code = main.Warehouse_code,
                                      Warehouse_name = main.Warehouse_name,
                                      zone_code = main.Zone_code,
                                      zone_name = main.Zone_name,
                                      Othoutord_wkeep = main.Othoutord_wkeep,
                                      Othoutord_time = main.Othoutord_time,
                                      Othoutord_audit_statua=main.Othoutord_audit_statua,
                                      Othoutord_status = main.Othoutord_status,
                                      Othoutord_audit_opinion=main.Othoutord_audit_opinion,
                                      othoutord_code_Associated=main.othoutord_code_Associated,
                                      Details = main.Details.Select(detail => new othoutordSelectDto.inv_othproddetailsInfo
                                      {
                                          Othproddetails_id = detail.Othproddetails_id,
                                          Othoutord_id = detail.Othoutord_id,
                                          Pro_name = detail.Pro_name,
                                          Pro_code = detail.Pro_code,
                                          Pro_brnad = detail.pro_brand,
                                          Pro_model = detail.Pro_model,
                                          unitmeas_id = detail.unitmeas_id,
                                          Othwrproddt_numder = detail.Othwrproddt_numder,
                                          stock_entry_no = detail.stock_entry_no,
                                          location_code = detail.location_code
                                      }).ToList()
                                  }).ToList();

            return result;
        } 
        /// <summary>
        /// 查询Count
        /// </summary>
        /// <param name="searchKeyword"></param>
        /// <param name="othwr_type"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Task<int> inv_othoutordCount(string ? searchKeyword, string othwr_type)
        {
            var query = myDbContext.inv_othoutord.AsQueryable();

            // 条件1: 入库类型筛选（如果提供了）
            if ((!string.IsNullOrEmpty(othwr_type)))
            {
                query = query.Where(x => x.Othoutord_type == othwr_type);
            }

            // 条件2: 关键字搜索（如果提供了）
            if (!string.IsNullOrEmpty(searchKeyword))
            {
                query = query.Where(x => x.Othoutord_code.Contains(searchKeyword));

            }
            query=query.Where(x=>x.Del_flag=='0');

            // 统计总数
            return query.CountAsync();
        }
        /// <summary>
        /// 删除其他出库单--其他出库单
        /// </summary>
        /// <param name="othoutord_id"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Task<int> Inv_othoutord_delete(int othoutord_id)
        {
            var inv_Othoutord=myDbContext.inv_othoutord.Where(x=>x.Othoutord_id==othoutord_id).FirstOrDefault();
            if (inv_Othoutord == null)
            {
                throw new Exception("未找到对应的出库单");
            }
            inv_Othoutord.Del_flag = '1';
            return myDbContext.SaveChangesAsync();
        }
        /// <summary>
        /// 修改审核状态--其他出库单
        /// </summary>
        /// <param name="inv_Othoutord"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> Inv_othoutord_examineUpdate(Inv_othoutord inv_Othoutord)
        {
            // 根据 Othoutord_code 查找出库单
            var othoutord = await myDbContext.inv_othoutord
                .FirstOrDefaultAsync(e => e.Othoutord_code == inv_Othoutord.Othoutord_code);

            if (othoutord == null)
            {
                throw new Exception("未找到对应的出库单");
            }

            // 更新审核信息
            othoutord.Othoutord_audit_by = inv_Othoutord.Othoutord_audit_by;
            othoutord.Othoutord_audit_time = inv_Othoutord.Othoutord_audit_time;
            othoutord.Othoutord_audit_statua = inv_Othoutord.Othoutord_audit_statua;
            othoutord.Othoutord_audit_opinion = inv_Othoutord.Othoutord_audit_opinion;

            // 保存更改
            return await myDbContext.SaveChangesAsync();

        }

        /// <summary>
        /// 根据编码查询其他出库单
        /// </summary>
        /// <param name="othoutord_code"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Task<List<Inv_othoutord>> Inv_trf_SelectCode(string othoutord_code)
        {
           var query=myDbContext.inv_othoutord.Where(x => x.Del_flag == '0' && x.Othoutord_code == othoutord_code).ToListAsync();
            return query;
        }
        /// <summary>
        /// 根据编码查询其他出库单详情
        /// </summary>
        /// <param name="othoutord_code"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<List<Inv_othproddetails>> Inv_trf_SelectDetail(string othoutord_code)
        {
            var query =await myDbContext.inv_othoutord.Where(x => x.Del_flag == '0' && x.Othoutord_code == othoutord_code).FirstOrDefaultAsync();

            if (query == null) { 
            throw new Exception("未找到对应的出库单");
            }
            var queryList=await myDbContext.inv_othproddetails.Where(x => x.Othoutord_id == query.Othoutord_id).ToListAsync();

            return queryList;
        }
        /// <summary>
        /// 根据编码查询ID，来添加详情其他出库单详细表
        /// </summary>
        /// <param name="otgwr_code"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> othproddetailsSelect_id(string otgwr_code)
        {
            var inv_othoutord=await myDbContext.inv_othoutord.FirstOrDefaultAsync(x => x.Othoutord_code == otgwr_code);

            if (inv_othoutord == null)
            {
                throw new Exception("未找到对应的出库单");
            }

            return inv_othoutord.Othoutord_id;
        }


        /// <summary>
        /// 新增其他出库单
        /// </summary>
        /// <param name="inv_Othoutord"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> Inv_othoutordAdd(Inv_othoutord inv_Othoutord)
        {
            await myDbContext.AddAsync(inv_Othoutord);                                                                                                                                
            return await myDbContext.SaveChangesAsync();
        } 
        /// <summary>
        /// 添加其他出库单的详情表
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> Inv_othproddetails(List<Inv_othproddetails> entities)
        {
            await myDbContext.AddRangeAsync(entities);
            return await myDbContext.SaveChangesAsync();
        }
        /// <summary>
        /// 修改出库状态
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public  Task<int> Inv_othproddetails_updateType(int id)
        {
            var query =  myDbContext.inv_othoutord.Where(x => x.Othoutord_id == id).FirstOrDefault();
            if (query == null) { 
            
            throw new Exception("未找到ID为" + id + "的其他出库单");
            }
            query.Othoutord_status = 1;
            return  myDbContext.SaveChangesAsync();
        }
        /// <summary>
        /// 修改其他出库单和同一时间修改为出库单详情
        /// </summary>
        /// <param name="inv_Othoutord"></param>
        /// <param name="inv_Othproddetails"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> Inv_othoutord_update(Inv_othoutord inv_Othoutord, List<Inv_othproddetails> inv_Othproddetails)
        {
            using var transaction = await myDbContext.Database.BeginTransactionAsync();
            try
            {
                // 1. 更新主表
                var existing = await myDbContext.inv_othoutord
                    .FirstOrDefaultAsync(o => o.Othoutord_id == inv_Othoutord.Othoutord_id);

                if (existing == null)
                    throw new Exception($"出库单 {inv_Othoutord.Othoutord_code} 不存在");

                existing.Othoutord_type = inv_Othoutord.Othoutord_type;
                existing.Warehouse_code = inv_Othoutord.Warehouse_code;
                existing.Warehouse_name = inv_Othoutord.Warehouse_name;
                existing.Zone_code = inv_Othoutord.Zone_code;
                existing.Zone_name = inv_Othoutord.Zone_name;
                existing.Othoutord_status = inv_Othoutord.Othoutord_status;
                
                existing.Othoutord_time = inv_Othoutord.Othoutord_time;
                existing.Update_by = inv_Othoutord.Update_by;
                existing.Update_time = inv_Othoutord.Update_time;

                myDbContext.Update(existing);
                await myDbContext.SaveChangesAsync();

                // 2. 取出原有明细
                var existingDetails = await myDbContext.inv_othproddetails
                    .Where(d => d.Othoutord_id == inv_Othoutord.Othoutord_id)
                    .ToListAsync();

                // 3. 识别三类记录
                var toAdd = new List<Inv_othproddetails>();
                var toUpdate = new List<Inv_othproddetails>();
                var toDeleteIds = existingDetails
                    .Where(d => !inv_Othproddetails.Any(e => e.Othproddetails_id == d.Othproddetails_id))
                    .Select(d => d.Othproddetails_id)
                    .ToList();

                foreach (var newItem in inv_Othproddetails)
                {
                    if (newItem.Othproddetails_id == 0 ||
                        !existingDetails.Any(d => d.Othproddetails_id == newItem.Othproddetails_id))
                    {
                        toAdd.Add(newItem);
                    }
                    else if (IsModified(existingDetails.First(d => d.Othproddetails_id == newItem.Othproddetails_id), newItem))
                    {
                        toUpdate.Add(newItem);
                    }
                }

                // 4. 执行差异操作
                if (toDeleteIds.Any())
                {
                    var delItems = existingDetails.Where(d => toDeleteIds.Contains(d.Othproddetails_id));
                    myDbContext.RemoveRange(delItems);
                }

                foreach (var item in toUpdate)
                {
                    var dbItem = existingDetails.First(d => d.Othproddetails_id == item.Othproddetails_id);
                    dbItem.Pro_name = item.Pro_name;
                    dbItem.Pro_code = item.Pro_code;
                    dbItem.pro_brand = item.pro_brand;
                    dbItem.Pro_model = item.Pro_model;
                    dbItem.unitmeas_id = item.unitmeas_id;
                    dbItem.Othwrproddt_numder = item.Othwrproddt_numder;
                    dbItem.Inventory_numder = item.Inventory_numder;
                    dbItem.location_code = item.location_code;
                    dbItem.location_name = item.location_name;
                    dbItem.pro_cost_price = item.pro_cost_price;
                    dbItem.pro_sale_price = item.pro_sale_price;

                    myDbContext.Update(dbItem);
                }

                foreach (var item in toAdd)
                {
                    item.Othoutord_id = inv_Othoutord.Othoutord_id;
                    await myDbContext.AddAsync(item);
                }

                await myDbContext.SaveChangesAsync();
                await transaction.CommitAsync();
                return 1;
            }
            catch (Exception ex)
            {
                await transaction.RollbackAsync();
                // logger.LogError(ex, "更新出库单失败");
                return 0;
            }
        }

        // 辅助方法：判断明细是否被修改
        private bool IsModified(Inv_othproddetails existing, Inv_othproddetails updated)
        {
            return existing.Pro_name != updated.Pro_name ||
                   existing.Pro_code != updated.Pro_code ||
                   existing.pro_brand != updated.pro_brand ||
                   existing.Pro_model != updated.Pro_model ||
                   existing.unitmeas_id != updated.unitmeas_id ||
                   existing.Othwrproddt_numder != updated.Othwrproddt_numder ||
                   existing.Inventory_numder != updated.Inventory_numder ||
                   existing.location_code != updated.location_code ||
                   existing.location_name != updated.location_name ||
                   existing.pro_cost_price != updated.pro_cost_price ||
                   existing.pro_sale_price != updated.pro_sale_price;
        }

    }
}
